[AWS IoT] CSRによる証明書の作成
1 はじめに
CX事業本部の平内(SIN)です。
AWS IoTへの接続で使用されるクライアント証明書は、1-Click証明書作成(推奨) で簡単に作成できます。証明書を作成 のボタンをクリックするだけで、Amazonルート認証局 (CA) によって署名されたクライアント証明書と秘密鍵がダウンロード可能となり、これをデバイス側に配置することで利用可能です。
通常、この要領で全く問題ありませんが、今回は、2つ目の選択にある CSRによる作成 による証明書の作成を試してみました。
CSRによる証明書作成では、クライアント側で所有する秘密鍵を使用しますので、秘密鍵の送達が必要ない仕組みを作ることが可能となります。
2 秘密鍵
CSR作成には、秘密鍵が必要です。下記は、Mac上で鍵長2048bitのRSA鍵を作成している様子です。
% openssl genrsa -out privatekey.pem 2048 Generating RSA private key, 2048 bit long modulus (2 primes) ...................................+++++ ...................................+++++ e is 65537 (0x010001) % ls -la privatekey.pem -rw------- 1 sin staff 1679 8 19 05:13 privatekey.pem
3 CSR
上記の秘密鍵を使用して、CSR(Certificate Signing Request)を作成している様子です。
% openssl req -new -subj "/C=JP/ST=Hokkaido/L=Sapporo/O=MyCompany/CN=AWS IoT Certificate" -key privatekey.pem -out cert.csr % ls -la cert.csr -rw-r--r-- 1 sin staff 1001 8 19 05:27 cert.csr
ディスティングイッシュネームは、とりあえず、下記のようになってます。
O | MyCompany |
L | Sapporo |
ST | Hokkaido |
C | JP |
CN | AWS IoT Certificate |
% openssl req -text -noout -in cert.csr Certificate Request: Data: Version: 1 (0x0) Subject: C = JP, ST = Hokkaido, L = Sapporo, O = MyCompany, CN = AWS IoT Certificate Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:aa:ac:84:30:fb:10:f8:c8:ab:fc:fe:86:97:7d: 9c:ca:71:af:e5:f4:b0:5b:42:86:b8:e5:36:06:ca: b2:04:20:49:c5:93:b5:4c:c5:67:80:ff:e8:e5:c4: f0:f7:ec:6b:6b:65:06:4c:ce:60:2b:db:a9:2c:6d: d9:4f:aa:a8:67:96:56:46:d4:8b:fe:f7:e5:09:77: 20:e7:a8:ea:4e:d0:4c:76:63:7d:89:ab:8c:71:6d: 87:9d:03:76:eb:53:ad:34:f7:08:ae:b8:98:21:ea: 74:a1:ad:a6:19:82:53:bc:6c:9d:09:a9:d6:af:bb: 67:51:b8:8c:08:c4:76:xx:xx:xx:1b:ee:f2:f8:30: 5a:2f:14:a4:d1:c4:9d:xx:xx:xx:04:02:98:82:4f: 8e:e1:36:16:6b:ef:8e:xx:xx:xx:38:70:6a:df:d8: b0:ac:f6:c0:a8:d9:f6:xx:xx:xx:87:0b:b4:43:b9: 45:6c:2b:f2:2c:0c:14:xx:xx:xx:92:66:e1:c9:12: 61:3a:5a:1e:6f:ea:00:31:29:ee:d9:14:73:4c:c7: b2:3f:bb:ce:86:45:f1:41:bc:0b:d6:b5:d7:c7:fa: b9:d9:3a:9c:12:b8:a4:0c:1e:d2:4d:ed:18:a9:00: 60:77:f9:96:0b:7b:ff:6b:99:9b:ec:3e:3a:23:04: af:a3 Exponent: 65537 (0x10001) Attributes: a0:00 Signature Algorithm: sha256WithRSAEncryption 4d:2b:ab:c7:6f:67:52:7a:05:9b:f4:46:a6:64:2f:60:ef:52: dc:ab:23:21:bd:e1:40:61:28:22:b8:e4:ac:2c:f8:8b:35:d1: d2:b2:bd:57:ac:0c:c8:1b:40:fc:e2:aa:50:bb:ac:1e:47:0d: dd:b0:12:b6:b7:11:1e:27:9a:dc:50:69:03:8a:90:64:87:71: 68:71:53:2d:2b:8e:bc:10:23:e9:4a:cf:de:78:88:2b:05:f5: 09:1d:0c:e4:a9:a2:f2:4a:1b:54:5b:b5:53:1c:cd:5c:8e:7a: 62:20:6e:9d:f1:61:6f:50:56:48:00:dd:eb:49:74:21:8d:ef: c3:f5:b1:f3:95:69:54:3e:xx:xx:xx:c9:2c:9b:93:35:f5:d9: 84:48:9c:ba:71:3d:b1:3a:xx:xx:xx:38:8b:ba:97:22:53:95: 2b:8d:27:57:b1:cd:a9:1f:xx:xx:xx:40:cb:ed:2e:01:68:f3: 4f:d9:cd:3c:d2:bc:9d:5c:xx:xx:xx:8a:28:8c:7d:24:fc:9a: 37:f1:24:3c:4f:f8:5c:07:xx:xx:xx:15:d5:b7:e6:ee:01:9b: 02:ec:ad:ea:35:2c:e2:00:2a:60:cc:b6:5c:78:f6:42:ec:32: 1c:06:89:5b:12:cd:2c:04:ad:c1:43:e1:a6:ac:a2:d0:fa:6d: d9:06:76:0d
4 レジストリへの登録
CSRによる作成を選択すると、ファイル選択となるので、作成したcert.csrを選択します。
ファイルアップロードをクリックすると証明書の作成が完了します。
証明書は、有効化して適当なポリシーを設定し、ダウンロードしてクライアントに配置しました。
% openssl x509 -text -noout -in 47f1008c07-certificate.pem.crt Certificate: Data: Version: 3 (0x2) Serial Number: 4b:9f:1f:0e:07:6c:e9:aa:25:f7:18:89:9a:76:12:d0:39:98:e0:fc Signature Algorithm: sha256WithRSAEncryption Issuer: OU = Amazon Web Services O=Amazon.com Inc. L=Seattle ST=Washington C=US Validity Not Before: Aug 18 20:29:23 2020 GMT Not After : Dec 31 23:59:59 2049 GMT Subject: C = JP, ST = Hokkaido, L = Sapporo, O = MyCompany, CN = AWS IoT Certificate Subject Public Key Info: Public Key Algorithm: rsaEncryption RSA Public-Key: (2048 bit) Modulus: 00:aa:ac:84:30:fb:10:f8:c8:ab:fc:fe:86:97:7d: 9c:ca:71:af:e5:f4:b0:5b:42:86:b8:e5:36:06:ca: b2:04:20:49:c5:93:b5:4c:c5:67:80:ff:e8:e5:c4: f0:f7:ec:6b:6b:65:06:4c:ce:60:2b:db:a9:2c:6d: d9:4f:aa:a8:67:96:56:46:d4:8b:fe:f7:e5:09:77: 20:e7:a8:ea:4e:d0:4c:76:63:7d:89:ab:8c:71:6d: 87:9d:03:76:eb:53:ad:34:f7:08:ae:b8:98:21:ea: 74:a1:ad:a6:19:82:xx:xx:xx:9d:09:a9:d6:af:bb: 67:51:b8:8c:08:c4:xx:xx:xx:cd:1b:ee:f2:f8:30: 5a:2f:14:a4:d1:c4:xx:xx:xx:1b:04:02:98:82:4f: 8e:e1:36:16:6b:ef:xx:xx:xx:97:38:70:6a:df:d8: b0:ac:f6:c0:a8:d9:xx:xx:xx:5d:87:0b:b4:43:b9: 45:6c:2b:f2:2c:0c:14:a5:fb:62:92:66:e1:c9:12: 61:3a:5a:1e:6f:ea:00:31:29:ee:d9:14:73:4c:c7: b2:3f:bb:ce:86:45:f1:41:bc:0b:d6:b5:d7:c7:fa: b9:d9:3a:9c:12:b8:a4:0c:1e:d2:4d:ed:18:a9:00: 60:77:f9:96:0b:7b:ff:6b:99:9b:ec:3e:3a:23:04: af:a3 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Authority Key Identifier: keyid:4F:3F:CE:F8:54:34:D3:2A:C8:FA:67:F3:A1:C3:9F:1F:76:73:62:6B X509v3 Subject Key Identifier: A7:13:9D:B7:49:F7:6E:6D:55:04:AE:D9:5E:06:E7:33:13:89:8C:BF X509v3 Basic Constraints: critical CA:FALSE X509v3 Key Usage: critical Digital Signature Signature Algorithm: sha256WithRSAEncryption ac:4d:be:61:21:7d:c2:be:8d:80:02:8d:2c:3f:d8:03:57:d1: d6:d5:c2:69:9d:b2:a7:20:2c:83:f6:72:48:21:d1:dd:9e:4a: 98:96:28:8a:2f:60:ec:d0:b7:20:9a:3c:e9:e7:e5:fc:03:5c: 11:09:42:29:0b:2b:bf:70:31:5c:25:ac:a6:3a:5a:2f:40:2f: b7:f4:58:5f:aa:1f:94:f2:57:f3:f3:8b:cb:71:8b:7d:6c:8d: d6:96:fe:36:af:08:9d:4d:66:f0:48:aa:3f:1c:4f:45:23:79: 48:e3:8b:b6:c0:b5:ad:42:xx:xx:xx:01:ee:b1:78:b3:c5:21: 7f:3d:cf:6a:20:89:4a:09:xx:xx:xx:29:05:43:0b:5a:82:3f: af:5c:74:b3:d8:64:d7:85:xx:xx:xx:67:73:56:2f:f2:e7:11: 36:b8:a4:6b:52:d8:b0:0d:xx:xx:xx:53:1e:0d:18:77:58:40: b2:51:21:17:92:bd:91:43:3e:cd:dc:d3:82:b6:ed:50:4d:d5: 52:ff:11:f3:11:76:fe:4c:d7:d3:b0:bb:c7:aa:fe:b9:a3:f8: b7:68:7e:32:c6:03:a4:61:18:03:e7:d8:2a:75:c9:40:3c:b1: 46:b6:ba:77:8e:b0:c9:fc:c0:10:2a:a5:aa:f8:ef:f6:4d:d5: ee:e1:cb:30
5 動作確認
動作確認に使用したコードは、以下の通りです。5秒に1回、カウント値をpublishしています。
from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient import time import json class Mqtt(): def __init__(self, endPoint, port, rootCA, certificate, privateKey, clientId): self.__client = AWSIoTMQTTClient(clientId) self.__client.configureEndpoint(endPoint, port) self.__client.configureCredentials(rootCA, privateKey, certificate) self.__client.configureAutoReconnectBackoffTime(1, 32, 20) self.__client.configureOfflinePublishQueueing(-1) self.__client.configureDrainingFrequency(2) self.__client.configureConnectDisconnectTimeout(10) self.__client.configureMQTTOperationTimeout(5) try: self.__client.connect() except Exception as e: print("ERROR {}".format(e)) def subscribe(self, topic, callback): self.__client.subscribe(topic, 1, callback) def publish(self, topic, payload): self.__client.publish(topic, payload, 1) def callback(client, userdata, data): print(data.payload.decode("utf-8")) def main(): endPoint = "xxxxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com" port = 8883 rootCA = "./root-CA.crt" privateKey = "./privatekey.pem" certificate = "./47f1008c07-certificate.pem.crt" clientId = "client-001" topic = "topic_001" mqtt = Mqtt(endPoint, port, rootCA, certificate, privateKey, clientId) mqtt.subscribe(topic, callback) counter = 0 while True: mqtt.publish(topic, json.dumps({ "counter": counter })) counter += 1 time.sleep(5) main()
6 最後に
手順は、非常に簡単でした。
最初に書いたとおり、この要領では、秘密鍵の送達が必要ありません。また、既存の秘密鍵を使いまわしたい場合も利用可能かも知れません。